package com.authine.cloudpivot.ext.applicationservice;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.data.support.PageImpl;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.domain.Entity.order.OrderCustomerGoodsEntity;
import com.authine.cloudpivot.ext.domain.dto.GoodsesBatchDto;
import com.authine.cloudpivot.ext.domain.dto.GoodsesBrandListDto;
import com.authine.cloudpivot.ext.domain.dto.base.Ids;
import com.authine.cloudpivot.ext.domain.dto.base.MallGoodsBatchDto;
import com.authine.cloudpivot.ext.domain.query.MallGoodsQuery;
import com.authine.cloudpivot.ext.enums.ReviewStatusEnum;
import com.authine.cloudpivot.ext.enums.goods.GoodsType;
import com.authine.cloudpivot.ext.utils.*;
import com.authine.cloudpivot.ext.utils.boQuery.BoQueryUtils;
import com.authine.cloudpivot.ext.utils.system.SessionUser;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.common.TableHelper;
import com.authine.mvp.app.launcher.domain.bo.BOList;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import io.swagger.models.auth.In;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.CollectionUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

@Path("MallService")
@Slf4j
public class MallService extends ApplicationService {

    String GOODS_SCHEMA_CODE = "t_goodses";
    String tableName = getTableName();
    NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);


    @Path("QueryTest")
    @POST
    @Operation(summary = "查询测试", tags = CUSTOM_SERVICE)
    public SingleResponse QueryTest(Ids dto) {

        List<String> goodsIds = JdbcTemplateUtils.builder(AppConst.ORDER_CENTER, ModelConst.T_ORDER_CUSTOMER_GOODS).selectField(" goods_id ").queryForList(String.class);
        log.info("goodsIds={}", goodsIds);


        PageImpl<OrderCustomerGoodsEntity> orderGoods = BoQueryUtils.Builder(ModelConst.T_ORDER_CUSTOMER_GOODS).condition().in("id", dto.getIds()).rpc(AppConst.ORDER_CENTER).listBO(OrderCustomerGoodsEntity.class);

        log.info("orderGoods={}", JSON.toJSONString(orderGoods.getContent()));

        return SingleResponse.of(null);
    }

    /**
     * 商品上架(驳回->审核中)
     * 条件: 已驳回 4
     * reviews_status  状态  4-> 2
     *
     * @param dto
     * @return
     */
    @Path("mallReject2Review")
    @POST
    @Operation(summary = "商城商品管理-商品上架(驳回->审核中)", tags = CUSTOM_SERVICE)
    public SingleResponse mallReject2Review(Ids dto) {

        log.info("===============商品商城上架 dto ={}", JSON.toJSONString(dto));

        if (dto.getIds() == null || dto.getIds() == null || dto.getIds().isEmpty()) {
            return SingleResponse.buildFailure("-1", "参数不能为空");
        }

        Integer count = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .selectField(" count(*) as count ")
                .eq("review_status", ReviewStatusEnum.REVIEW_DISAGREE.ordinal())
                .in("id", dto.getIds())
                .queryForObject(Integer.class);

        log.info("===================count ={}", count);


        if (count == null || count.intValue() != dto.getIds().size()) {
            return SingleResponse.buildFailure("-1", "非已驳回的商品不能申请手动上架为审核中");
        }

        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .putFieldAndVal("review_status", ReviewStatusEnum.UNDER_REVIEW.ordinal())
                .in("id", dto.getIds())
                .update();

        log.info("==============update ={}", update);


        return SingleResponse.buildSuccess();
    }


    /**
     *  商品商城撤销至未审核
     *  任何状态都可以撤销至未审核  (1,2,3,4) -> 0
     * @param dto
     * @return
     */
    @Path("mallRevoke")
    @POST
    @Operation(summary = "商城商品管理-撤销至未审核", tags = CUSTOM_SERVICE)
    public SingleResponse mallRevoke(Ids dto) {
        log.info("===============商品商城撤销至未审核 dto ={}", JSON.toJSONString(dto));

        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .putFieldAndVal("review_status", ReviewStatusEnum.UN_REVIEWED.ordinal())
                .in("id", dto.getIds())
                .update();

        log.info("==============update ={}", update);

        if (update > 0) {
            return SingleResponse.buildSuccess();
        } else {
            return SingleResponse.buildFailure("-1", "更新失败,数据不存在");
        }


    }

    /**
     *  待提交或已驳回的 提交审核
     *  条件 review_status 1,4
     *  结果 review_status 2
     * @param dto
     * @return
     */
    @Path("mallReview")
    @POST
    @Operation(summary = "商城商品管理-提交审核", tags = CUSTOM_SERVICE)
    public SingleResponse mallReview(Ids dto) {
        log.info("===============商品商城提交审核 dto ={}", JSON.toJSONString(dto));

        StringBuilder sql = new StringBuilder("select count(*) as count from ").append(tableName)
                .append(" where id in (:id) and review_status in (:review_status)") ;

        MapBuilder  temp = MapBuilder.create(new HashMap<String,Object>()).put("id", dto.getIds())
                .put("review_status", new ArrayList(Arrays.asList(new Integer[]{1, 4})));


        Integer count = jdbcTemplate.queryForObject(sql.toString(), temp.build(), Integer.class);
        log.info("==============count ={}", count);

        if (count == null || count.intValue() != dto.getIds().size() ){
            return  SingleResponse.buildFailure("-1","存在审核中或审核通过的商品,不能提交审核");
        }

        sql.setLength(0);
        sql = new StringBuilder("update ").append(tableName)
                .append(" set review_status=:review_status1 where id in (:id) and review_status in (:review_status)");
        temp.put("review_status1", ReviewStatusEnum.UNDER_REVIEW.ordinal());

        int update = jdbcTemplate.update(sql.toString(), temp.build());

        log.info("==============update ={}", update);


        return  SingleResponse.buildSuccess();
    }

    /**
     *   商城添加商品到待提交或审核中, 并修改调整比例
     *   review_status 0->1 or 2
     *   adjust_ratio
     * @param dto
     * @return
     */
    @Path("mallAdd")
    @POST
    @Operation(summary = "商城商品管理-添加商品(未审核改为其他状态)", tags = CUSTOM_SERVICE)
    public SingleResponse mallAdd(GoodsesBatchDto dto) {
        log.info("===============商城添加商品 dto ={}", JSON.toJSONString(dto));


        if (dto.getReviewStatus() == null || dto.getAdjustRatio() == null
                || !reviewEnumContains(dto.getReviewStatus(), ReviewStatusEnum.PENDING, ReviewStatusEnum.UNDER_REVIEW)) {
            return SingleResponse.buildFailure("-1", "添加商品 参数值不合法");
        }

        //todo  固买代码需要重新计算加点价格 /重新计算加点的价格 cn/gomro/core/bizes/platform_shop/service/impl/IShopGoodsServiceImpl.java:179

        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .putFieldAndVal("review_status", dto.getReviewStatus())
                .putFieldAndVal("adjust_ratio", dto.getAdjustRatio())
                .in("id", dto.getIds())
                .eq("review_status", ReviewStatusEnum.UN_REVIEWED.ordinal())
                .update();


        log.info("==============update ={}", update);


        return SingleResponse.buildSuccess();
    }

    /**
     *
     * @param status
     * @param enums
     * @return
     */
    private boolean reviewEnumContains(Integer status,ReviewStatusEnum ...enums){

        return  ArrayUtil.contains(enums,ReviewStatusEnum.getEnum(status));
    }

    /**
     *   调整比例
     * @param dto
     * @return
     */
    @Path("updateAdjustRatio")
    @POST
    @Operation(summary = "商城商品管理-调整比例", tags = CUSTOM_SERVICE)
    public SingleResponse updateAdjustRatio(GoodsesBatchDto dto) {
        log.info("===============调整比例 dto ={}", JSON.toJSONString(dto));

        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .putFieldAndVal("adjust_ratio", dto.getAdjustRatio())
                .in("id", dto.getIds())
                .update();


        log.info("==============update ={}", update);

        return SingleResponse.buildSuccess();
    }

    /**
     * 平台调整比例
     *
     * @param dto
     * @return
     */
    @Path("updatePlatformAdjustRatio")
    @POST
    @Operation(summary = "商城商品管理--平台调整比例", tags = CUSTOM_SERVICE)
    public SingleResponse updatePlatformAdjustRatio(GoodsesBatchDto dto) {
        log.info("===============调整比例 dto ={}", JSON.toJSONString(dto));

        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .putFieldAndVal("platform_adjust_ratio", dto.getAdjustRatio())
                .in("id", dto.getIds())
                .update();

        log.info("==============update ={}", update);

        return SingleResponse.buildSuccess();
    }


    /**
     *   审批 : 审批中 到  审批通过或 已驳回
     *   review_status 2->3,4
     * @param dto
     * @return
     */
    @Path("toReview")
    @POST
    @Operation(summary = "商城商品管理-审批或驳回", description = "由审批中2的状态 到 审批通过3 或 驳回4 ; 需要参数: id,review_status", tags = CUSTOM_SERVICE)
    public SingleResponse toReview(GoodsesBatchDto dto) {
        log.info("===============调整比例 dto ={}", JSON.toJSONString(dto));



        if (!reviewEnumContains(dto.getReviewStatus(),ReviewStatusEnum.REVIEW_CONSENT,ReviewStatusEnum.REVIEW_DISAGREE)){
            return  SingleResponse.buildFailure("-1","参数不合法");
        }


        StringBuilder sql = new StringBuilder("select count(*) as count from ").append(tableName)
                .append(" where id in (:id) and review_status =:review_status") ;

        MapBuilder  temp = MapBuilder.create(new HashMap<String,Object>()).put("id", dto.getIds())
                .put("review_status",ReviewStatusEnum.UNDER_REVIEW.ordinal());

        Integer count = jdbcTemplate.queryForObject(sql.toString(), temp.build(), Integer.class);
        log.info("==============count ={}", count);

        if (count == null || count.intValue() != dto.getIds().size() ){
            return  SingleResponse.buildFailure("-1","存在非审核中的数据,不能审批");
        }

        sql = new StringBuilder("update ").append(tableName)
                .append(" set review_status=:review_status ,review_content=:review_content  where id in (:id) and review_status=:review_status1") ;


        temp.put("review_status",dto.getReviewStatus())
                .put("review_status1",ReviewStatusEnum.UNDER_REVIEW.ordinal())
                .put("review_content", Optional.ofNullable(dto.getReviewContent()).orElse(""));

        int update = jdbcTemplate.update(sql.toString(), temp.build());
        log.info("==============update ={}", update);

        return  SingleResponse.buildSuccess();
    }



    /**
     *  下架
     *  saled
     *  mall_featured
     * @param dto
     * @return
     */
    @Path("downSaled")
    @POST
    @Operation(summary = "商城商品管理-mall_sales下架", tags = CUSTOM_SERVICE)
    public SingleResponse downSaled(GoodsesBatchDto dto) {
        log.info("===============上架 dto ={}", JSON.toJSONString(dto));

        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .putFieldAndVal("mall_sales", 0)
                .in("id", dto.getIds())
                .update();

        log.info("==============update ={}", update);

        return SingleResponse.buildSuccess();
    }


    /**
     *  上架并修改是否精选
     *  saled
     *  mall_featured
     * @param dto
     * @return
     */
    @Path("upSaledAndFeatured")
    @POST
    @Operation(summary = "商城商品管理-上架并修改是否精选", tags = CUSTOM_SERVICE)
    public SingleResponse upSaledAndFeatured(GoodsesBatchDto dto) {
        log.info("===============上架并修改是否精选 dto ={}", JSON.toJSONString(dto));


        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .putFieldAndVal("mall_sales", dto.getSaled())
                .putFieldAndVal("mall_featured", dto.getMallFeatured())
                .in("id", dto.getIds())
                .update();

        log.info("==============update ={}", update);

        return SingleResponse.buildSuccess();
    }



    @Path("brandListInfo")
    @POST
    @Operation(summary = "商城商品管理-获取品牌列表聚合数据", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> brandListInfo(GoodsesBrandListDto dto ){


        StringBuilder sqlData = new StringBuilder();
        sqlData.append("SELECT temp.* ,(temp.alls -temp.saled) as noSaled, (temp.alls-temp.featured) as noFeatured from ( " +
                "SELECT  brand,org_fullname,count(*) as alls, sum(saled) as saled,sum(mall_featured) as featured " +
                "from i_commoditymaterials_t_goodses  " );

        StringBuilder sqlCount = new StringBuilder();
        sqlCount.append("SELECT count(*) as count from ( " +
                "SELECT count(*) from i_commoditymaterials_t_goodses   "
               );

        MapBuilder<String, Object> mapBuilder = MapBuilder.create(new HashMap<>());
        if (!StringUtils.isNull(dto.getBrand())){
            sqlData.append(" where brand like :brand  ");
            sqlCount.append(" where brand like :brand  ");
            mapBuilder.put("brand", "%".concat(dto.getBrand()).concat("%") );
        }
        sqlData.append("GROUP BY brand,org_fullname ORDER BY brand   ) as temp ")
                .append(dto.limit());

        sqlCount.append( " GROUP BY brand,org_fullname  ) temp ");

        Integer count = jdbcTemplate.queryForObject(sqlCount.toString(), mapBuilder.build(), Integer.class);

        List<Map<String, Object>> list = jdbcTemplate.queryForList(sqlData.toString(), mapBuilder.build());

        BOList boList = new BOList();

        boList.setTotal(count);
        boList.setData(list);

        return SingleResponse.of(boList);
    }


    private String getTableName() {
        return ApplicationContextUtils.getBean(TableHelper.class).getTableName(GOODS_SCHEMA_CODE);
    }

    @Path("convertToMall")
    @POST
    @Operation(summary = "商城商品管理-转为客户商城", tags = CUSTOM_SERVICE)
    public SingleResponse convertToMall(MallGoodsBatchDto mallGoodsBatchDto){
        //判断查询条件
        Assert.notEmpty(mallGoodsBatchDto.getIds(), "商品id不能为空");
        Assert.notNull(mallGoodsBatchDto.getOrganizationId(), "客户组织id不能为空!");
        Assert.notNull(mallGoodsBatchDto.getOrganizationName(), "客户组织名称不能为空!");
        List<String> ids = mallGoodsBatchDto.getIds();
        //查询数据库,是否被绑定
        List<Map<String, Object>> maps = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .selectField("id,relation_goods_id")
                .eq("JSON_UNQUOTE(organization_id -> '$.id')", mallGoodsBatchDto.getOrganizationId().get("id"))
                .in("relation_goods_id", ids).queryForList();
        List<String> relationGoodsIds= maps.stream().map(a -> String.valueOf(a.get("relation_goods_id"))).filter(a -> ids.contains(a)).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(relationGoodsIds)){
            String lettersCommaSeparated = String.join(",", relationGoodsIds);
            return SingleResponse.buildFailure("-1", "商品编号"+lettersCommaSeparated+"已经转入该客户商城，请勿重复转入");
        }
        //
        //检查商品是否存在
        List<Map<String, Object>> goodsMaps = JdbcTemplateUtils.builder(ModelConst.T_GOODSES)
                .selectField("*")
                .in("id",ids).queryForList();

        if (CollectionUtils.isEmpty(goodsMaps)){
            return SingleResponse.buildFailure("-2", "商品不存在!");
        }
        setMallMaps(mallGoodsBatchDto, goodsMaps);

        SingleResponse<BO> bo = BoServiceUtils.createBo(ModelConst.T_GOODSES, goodsMaps);
        return bo;
    }


    @Path("selectMallGoods")
    @POST
    @Operation(summary = "商城商品管理-查看企业商城", tags = CUSTOM_SERVICE)
    public BOList selectMallGoods(MallGoodsQuery mallGoodsQuery){
        log.info("开始查询商城商品管理-查看企业商城,参数为:{}",mallGoodsQuery);

        Integer integer=0;

        String goodsId = mallGoodsQuery.getGoodsId();
        String name = mallGoodsQuery.getName();
        String brand = mallGoodsQuery.getBrand();

        StringBuilder selectSql=  new StringBuilder("select * from ").append(tableName);

        StringBuilder countSqlBuilder=new StringBuilder("select COUNT(1) from ").append(tableName);
        Map<String,  Object> params = MapUtil.newHashMap(7);


        StringBuilder whereSql=new  StringBuilder(" where 1=1 ");
        if (StringUtils.isNotBlank(goodsId)){
            whereSql.append(" and id =:id ");
            params.put("id",goodsId);
        }

        if (StringUtils.isNotBlank(name)){
            whereSql.append(" and name =:name ");
            params.put("name",name);
        }


        if (StringUtils.isNotBlank(brand)){
            whereSql.append(" and brand =:brand ");
            params.put("brand",brand);
        }

        whereSql.append(" and type =:type ");
        //设置查询企业商城
        params.put("type",GoodsType.EnterpriseMall.ordinal());
        //设置查询企业商城


        SessionUser sessionUser=new SessionUser();
        if (sessionUser.isPm()){
            String currentOrgID = sessionUser.getCurrentOrgID();
            whereSql.append(" and JSON_UNQUOTE(organization_id -> '$.id') =:currentOrgID");
            params.put("currentOrgID",currentOrgID);
        }


        String sql = selectSql.append(whereSql).append(" limit ").append(mallGoodsQuery.getPage()-1).append(",").append(mallGoodsQuery.getLimit()).toString();
        log.info("企业商城查询列表语句为:{},参数为:{}",JSONObject.toJSONString(sql),JSONObject.toJSONString(params));
        //查询数据库
        List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, params);

        BoResultFormat.resultFormat(mapList,ModelConst.T_GOODSES);

       String  sqlCount = countSqlBuilder.append(whereSql).toString();
        //查询数量
        if (!CollectionUtils.isEmpty(mapList)){
             integer = jdbcTemplate.queryForObject(sqlCount, params, Integer.class);
        }
        BOList boList = new BOList();
        boList.setTotal(integer);
        boList.setData(mapList);

        return  boList;
    }



    /**
     * 设置新增map
     * @param mallGoodsBatchDto
     * @param goodsMaps
     */
    private void setMallMaps(MallGoodsBatchDto mallGoodsBatchDto, List<Map<String, Object>> goodsMaps) {
        BoResultFormat.resultFormat(goodsMaps,ModelConst.T_GOODSES);

        //处理数据
        goodsMaps.forEach(x->{
            x.put("organization_name", mallGoodsBatchDto.getOrganizationName());
            x.put("type", GoodsType.EnterpriseMall.ordinal());
            x.put("organization_id", mallGoodsBatchDto.getOrganizationId());
            x.put("platform_adjust_ratio",new BigDecimal(0));
            x.put("adjust_pretax_price",x.get("pretax_price"));
            x.put("adjust_price",x.get("price"));
            x.put("adjust_ratio",new BigDecimal(0));
            x.put("review_content",null);
            x.put("stock",null);
            x.put("review_status",ReviewStatusEnum.UN_REVIEWED.ordinal());
            x.put("mall_sales",false);
            x.put("relation_goods_id",x.get("id"));
            x.put("adjust_price",x.get("price"));
            x.remove("id");
            x.remove("createdBy");
            x.remove("createdDept");
            x.remove("createdTime");
            x.remove("owner");
            x.remove("ownerDept");
            x.remove("modifiedBy");
            x.remove("modifiedTime");
            x.remove("deleted");
        });
    }


}
